import React, { useRef, useEffect } from 'react';
import * as THREE from 'three';
import './canvasBg.scss'
const Pointwave = ({ amountX = 50, amountY = 50, color = 0xffffff, top = 350 }) => {
  const containerRef = useRef(null);
  const mouseX = useRef(0);
  const windowHalfX = useRef(0);
  const count = useRef(0);

  useEffect(() => {
    let camera, scene, particles, renderer;

    const SEPARATION = 100;
    const SCREEN_WIDTH = window.innerWidth;
    const SCREEN_HEIGHT = window.innerHeight;
    windowHalfX.current = window.innerWidth / 2;

    // 初始化Three.js场景
    const init = () => {
      camera = new THREE.PerspectiveCamera(75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000);
      camera.position.z = 1000;

      scene = new THREE.Scene();

      const numParticles = amountX * amountY;
      const positions = new Float32Array(numParticles * 3);
      const scales = new Float32Array(numParticles);

      let i = 0, j = 0;
      for (let ix = 0; ix < amountX; ix++) {
        for (let iy = 0; iy < amountY; iy++) {
          positions[i] = ix * SEPARATION - (amountX * SEPARATION) / 2;
          positions[i + 1] = 0;
          positions[i + 2] = iy * SEPARATION - (amountY * SEPARATION) / 2;
          scales[j] = 1;
          i += 3;
          j++;
        }
      }

      const geometry = new THREE.BufferGeometry();
      geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
      geometry.setAttribute('scale', new THREE.BufferAttribute(scales, 1));

      const material = new THREE.ShaderMaterial({
        uniforms: {
          color: { value: new THREE.Color(color) },
        },
        vertexShader: `
          attribute float scale;
          void main() {
            vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
            gl_PointSize = scale * (300.0 / -mvPosition.z);
            gl_Position = projectionMatrix * mvPosition;
          }
        `,
        fragmentShader: `
          uniform vec3 color;
          void main() {
            if (length(gl_PointCoord - vec2(0.5, 0.5)) > 0.475) discard;
            gl_FragColor = vec4(color, 1.0);
          }
        `,
      });

      particles = new THREE.Points(geometry, material);
      scene.add(particles);

      renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
      renderer.setSize(containerRef.current.clientWidth, containerRef.current.clientHeight);
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setClearAlpha(0);
      containerRef.current.appendChild(renderer.domElement);
    };

    const animate = () => {
      requestAnimationFrame(animate);
      render();
    };

    const render = () => {
      camera.position.x += (mouseX.current - camera.position.x) * 0.05;
      camera.position.y = 400;
      camera.lookAt(scene.position);

      const positions = particles.geometry.attributes.position.array;
      const scales = particles.geometry.attributes.scale.array;

      let i = 0, j = 0;
      for (let ix = 0; ix < amountX; ix++) {
        for (let iy = 0; iy < amountY; iy++) {
          positions[i + 1] = Math.sin((ix + count.current) * 0.3) * 100 + Math.sin((iy + count.current) * 0.5) * 100;
          scales[j] = (Math.sin((ix + count.current) * 0.3) + 1) * 8 + (Math.sin((iy + count.current) * 0.5) + 1) * 8;
          i += 3;
          j++;
        }
      }

      particles.geometry.attributes.position.needsUpdate = true;
      particles.geometry.attributes.scale.needsUpdate = true;
      renderer.render(scene, camera);

      count.current += 0.01;
    };

    const onWindowResize = () => {
      windowHalfX.current = window.innerWidth / 2;
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    };

    const onDocumentMouseMove = (event) => {
      mouseX.current = event.clientX - windowHalfX.current;
    };

    const onDocumentTouchStart = (event) => {
      if (event.touches.length === 1) {
        mouseX.current = event.touches[0].pageX - windowHalfX.current;
      }
    };

    const onDocumentTouchMove = (event) => {
      if (event.touches.length === 1) {
        event.preventDefault();
        mouseX.current = event.touches[0].pageX - windowHalfX.current;
      }
    };

    // 初始化
    init();
    animate();

    // 添加事件监听器
    window.addEventListener('resize', onWindowResize, false);
    document.addEventListener('mousemove', onDocumentMouseMove, false);
    document.addEventListener('touchstart', onDocumentTouchStart, false);
    document.addEventListener('touchmove', onDocumentTouchMove, false);

    return () => {
      // 清理工作
      window.removeEventListener('resize', onWindowResize);
      document.removeEventListener('mousemove', onDocumentMouseMove);
      document.removeEventListener('touchstart', onDocumentTouchStart);
      document.removeEventListener('touchmove', onDocumentTouchMove);
    };
  }, []);

  return (
    <div id="indexLizi" ref={containerRef} style={{ width: '100%', height: '100vh', position: 'relative', top: `${top}px` }} />
  );
};

export default Pointwave;